#include <stdio.h>
#include <sys/socket.h>
#include <linux/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

/*通过udp发送数据
如果发送成功返回发送的字节数， 如果失败-1 
*/
int udp_send(int sockfd, struct sockaddr_in *addr, const void *buf, int len)
{
	int sendsize = sendto(sockfd, buf, len, 0, (struct sockaddr*)addr, sizeof(struct sockaddr));
	if(sendsize < 0)
	{
		perror("send fail1");
		return -1;
	}
	int size = 0;
	int ret = recvfrom(sockfd, &size, 4, 0, NULL, NULL);//返回值即接收大小，  size即存放缓存区
	if(sendsize == size)
	{
			
		printf("sendsize%d\n",sendsize);
		printf("size=%d\n",size);
		return sendsize;
	}
	else 
	{
		printf("sendsize%d\n",sendsize);
		printf("size=%d\n",size);
		return -1;	

	}
}


//发送端---创建套接字socket---发送数据sendto
int main(int argc , char **argv) // .udpsend 192.168.14.11 1234 ../aaa.c
{
	if(argc<4)
	{
		printf("Using:udpsend  ip port");
		return 0;
	}
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);


	struct sockaddr_in toaddr;
	memset(&toaddr, 0, sizeof(toaddr));
	toaddr.sin_family = AF_INET;  //ipv4
	toaddr.sin_port = htons(atoi(argv[2])); //传入链接端口
	toaddr.sin_addr.s_addr = inet_addr(argv[1]);//传入链接ip

	char sendbuf[1024] = {0};
	
	//获取文件大小
	struct stat sts;
	stat(argv[3], &sts);
	unsigned int filesize = sts.st_size;   //文件大小
	char *p = argv[3];
	char *q = p+strlen(argv[3]);
	while(q != p && *q != '/')
	{
		q--;
	}
	if(q != p)
	{
		q++;
	}
	char filename[strlen(q) + 1]; 
	strcpy(filename, q);        //获取文件名
	printf("%s\n",filename);

	char fileinfo[4+strlen(filename)+1];  //存储文件大小，文件名
	memset(fileinfo, 0, sizeof(fileinfo));
	memcpy(fileinfo, &filesize, 4);//把文件大小放在fileinfo的前面4个字节中
	memcpy(fileinfo+4, filename, strlen(filename)); //把文件名放在fileinfo的文件大小后面
	
	udp_send(sockfd, &toaddr, fileinfo, sizeof(fileinfo));

	//打开文件
	FILE *file = fopen(argv[3], "r");

	while(1)
	{
		//读取文件----
		int ret = fread(sendbuf, 1, 1024, file);
		if(ret <= 0)
			break;

		ret = udp_send(sockfd, &toaddr, sendbuf, ret);
		if(ret < 0)
		{
			printf("send fail2");
		}
	}

	fclose(file);
	return 0;
}
